<?php


namespace App\Services;


use App\Models\Task;
use App\Models\Papper;
use App\Models\PapperTitle;
use App\Models\PapperNeed;
use App\Models\PapperVideo;
use App\Services\FolderService;
use App\Utils\Code;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class PapperService extends BaseService
{
    /**
     * 创建数据
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function store(array $params) {
        if (!$this->checkParams($params)){
            throw new \Exception('请求参数验证不通过', Code::PARAMETER_ERROR);
        }
        if (Papper::where('folder_id', $params['folder_id'])->where('index', $params['index'])->exists()){
            throw new \Exception('该文件夹下已存在相同序号的文案', Code::PARAMETER_ERROR);
        }
        return DB::transaction(function () use ($params){
            $model = new Papper();
            $model->folder_id = $params['folder_id'];
            $model->index = $params['index'];
            $model->user_id = $this::$userId;
            if (isset($params['ip_id']) && $params['ip_id']){
                $model->ip_id = $params['ip_id'];
            }
            if (isset($params['content']) && $params['content']){
                $model->content = $params['content'];
            }
            if (isset($params['type']) && $params['type']){
                $model->type = $params['type'];
            }
            $model->save();
            return $model;
        });
    }

    /**
     * 数据信息
     * @param $id
     * @param bool $simple
     * @param bool $abnormal
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function show($id, $abnormal = true, $simple = true) {
        $model = Papper::where('id', $id);
        if (!$simple) {
            $model = $model->with(['folder', 'need']);
        }
        $model = $model->first();
        if (!$model && $abnormal){
            throw new \Exception('不存在的ID', Code::EMPTY_DATA);
        }
        return $model;
    }

    /**
     * 更新数据
     * @param $id
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function update($id, array $params) {
        if (isset($params['is_kpi']) && $params['is_kpi']) {
            return DB::transaction(function () use ($id, $params){
                $taskMap = [
                    1 => 0.25, // 文案任务
                    2 => 0.15, // 拍摄任务 
                    3 => 0.5,  // 剪辑任务
                    4 => 0.1   // 发布任务
                ];
                $model = $this->show($id);
                $keys = ['number1', 'number2', 'number3', 'number4'];
                foreach($keys as $key) {
                    if (isset($params[$key]) && is_numeric($params[$key])){
                        $model[$key] = $params[$key];
                    }
                }
                if (isset($params['pinggu_status']) && is_numeric($params['pinggu_status'])) {
                    $model['pinggu_status'] = $params['pinggu_status'];
                }
                if (isset($params['pinggu_status']) && $params['pinggu_status']) {
                    $model['pinggu_date'] = $params['pinggu_date'];
                }
                if ($model['pinggu_status'] == 1 && ($model['number1'] <= 0 || $model['number2'] <= 0 || $model['number3'] <= 0)) {
                    throw new \Exception('文案未设置绩效分，无法评估', Code::PARAMETER_ERROR);
                }
                //任务绩效分=任务系数*【难度系数*【 效果分=（10*  点赞数+0.1* 播放量）* 转化效率】】
                $model->number5 = (0.1 * $model->number2 + 0.001 * $model->number3) * $model->number4;
                $model->number6 = $model->number1 * 100 + $model->number5;
                $tasks = Task::where('papper_id', $id)->get();
                foreach($tasks as $task) {
                    $task->number1 = $model->number1;
                    $task->number2 = $model->number5;
                    $task->number3 = $model->number6 * $taskMap[$task->type];
                    $task->pinggu_status = $model->pinggu_status;
                    $task->pinggu_date = $model->pinggu_date;
                    $task->save();
                }
                $model->save();
                return $this->show($id);
            });
        } elseif (isset($params['is_need']) && $params['is_need']) {
            return DB::transaction(function () use ($id, $params){
                if (!$needModel = PapperNeed::where('papper_id', $id)->first()) {
                    $needModel = new PapperNeed();
                    $needModel->papper_id = $id;
                }
                if (isset($params['title']) && $params['title']){
                    $needModel->title = $params['title'];
                }
                if (isset($params['path']) && $params['path']){
                    $needModel->path = $params['path'];
                }
                if (isset($params['images']) && $params['images']){
                    $needModel->images = $params['images'];
                }
                return $needModel->save();
            });
        } else {
            if (!$this->checkParams($params, true)){
                throw new \Exception('请求参数验证不通过', Code::PARAMETER_ERROR);
            }
            return DB::transaction(function () use ($id, $params){
                $model = $this->show($id);
                if (isset($params['name']) && $params['name']){
                    $model->name = $params['name'];
                }
                if (isset($params['content']) && $params['content']){
                    $model->content = $params['content'];
                }
                if (isset($params['number1']) && is_numeric($params['number1'])){
                    $model->number1 = $params['number1'];
                }
                if (isset($params['status']) && is_numeric($params['status'])){
                    $model->status = (int)$params['status'];
                }
                if (isset($params['ip_id']) && is_numeric($params['ip_id'])){
                    $model->ip_id = (int)$params['ip_id'];
                }
                if (isset($params['folder_id']) && is_numeric($params['folder_id'])){
                    $model->folder_id = (int)$params['folder_id'];
                }
                if (isset($params['titles']) && $params['titles'] && is_array($params['titles'])) {
                    if (!$title = PapperTitle::where('papper_id', $model->id)->first()) {
                        $title = new PapperTitle();
                        $title->papper_id = $model->id;
                        $title->titles = $params['titles'];
                        $title->save();
                    }
                    $title->titles = $params['titles'];
                    $title->save();
                }
                if (isset($params['images'])) {
                    $model->images = $params['images'];
                }
                $model->save();
                return $this->show($id);
            });
        }
    }

    /**
     * 删除数据
     * @param $id
     * @return mixed
     * @throws \Exception
     */
    public function destroy(array $ids = []) {
        if (!$this::$admin) {
            throw new \Exception('你没有权限进行删除', Code::LACK_OF_CONDITIONS);
        }
        return DB::transaction(function () use ($ids) {
            return Papper::whereIn('id', $ids)->delete();
        });
    }

    /**
     * 数据分页
     * @param array $params
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function lists(array $params = []) {
        if (isset($params['mode']) && $params['mode'] == 'select') {
            $model = Papper::select(['id']);
        } else {
            $model = Papper::with([
                'ip',
                'title',
                'folder',
                'tasks',
                'need',
                'video',
                'user'
            ])->withCount(['footages']);
        }
        if (!$this::$admin) {
            $model = $model->whereHas('tasks', function ($query){
                $query->where('user_id', '=', $this::$userId)->where('type', 1);
            });
        }
        if (isset($params['folder_id']) && $params['folder_id']) {
            $model = $model->where('folder_id', '=', $params['folder_id']);
        }
        if (isset($params['ip_id']) && $params['ip_id']) {
            $model = $model->where('ip_id', '=', $params['ip_id']);
        }
        if (isset($params['user_id']) && $params['user_id']) {
            $model = $model->where('user_id', '=', $params['user_id']);
        }
        if (isset($params['status']) && $params['status']) {
            $model = $model->where('status', '=', (int)$params['status']);
        }
        if (isset($params['type']) && $params['type']) {
            $model = $model->where('type', '=', (int)$params['type']);
        }
        if (isset($params['name']) && $params['name']) {
            $model = $model->where('name', 'like', '%'.$params['name'].'%');
        }
        if (isset($params['task_status']) && is_numeric($params['task_status'])){
            if ($params['task_status'] == 1) {
                $model = $model->whereHas('tasks');
            } elseif ($params['task_status'] == 0) {
                $model = $model->whereDoesntHave('tasks');
            }
        }
        if (isset($params['created_at']) && $params['created_at']) {
            $params['created_at'] = explode(',', $params['created_at']);
            $model = $model->where('created_at', '>=', $params['created_at'][0]);
            $model = $model->where('created_at', '<=', $params['created_at'][1]);
        }
        $lists = $model->orderBy('id', 'desc')->paginate(isset($params['per_page']) ? (int)$params['per_page'] : 15);
        return $lists;
    }

    /**
     * 验证参数
     * @param array $params
     * @param bool $isUpdate
     * @return array
     * @throws \Exception
     */
    private function checkParams(array $params, $isUpdate = false){
        $rules = [
            'folder_id' => ['bail', 'required', 'integer'],
            'index' => ['bail', 'required', 'integer'],
            'ip_id' => ['bail', 'nullable', 'integer'],
            'content' => ['bail', 'nullable', 'string'],
            'status' => ['bail', 'nullable', 'integer'],
        ];
        if ($isUpdate){
            // 删除必选条件
            foreach ($rules as $field => &$rule){
                if (isset($rule[1]) && $rule[1] == 'required') {
                    unset($rule[1]);
                }
            }
        }
        $validator = Validator::make($params, $rules, [], [
            'folder_id' => '文件夹ID',
            'index' => '序号',
            'ip_id' => 'IP编号',
            'content' => '内容',
            'status' => '状态'
        ]);
        if ($validator->fails()) {
            throw new \Exception($validator->errors()->first(), Code::PARAMETER_ERROR);
        }
        return $params;
    }
    
    // 新增视频
    public function addVideo(array $params) {
        if (!isset($params['video_ids']) || !is_array($params['video_ids'])) {
            throw new \Exception('视频ID不能为空', Code::PARAMETER_ERROR);
        }
        if (!isset($params['papper_id']) || !$params['papper_id']) {
            throw new \Exception('文案ID不能为空', Code::PARAMETER_ERROR);
        }
        return DB::transaction(function () use ($params){
            if (!Papper::where('id', $params['papper_id'])->exists()) {
                throw new \Exception('文案不存在', Code::EXIST_REPEAT);
            }
            PapperVideo::where('papper_id', $params['papper_id'])->delete();
            $sort = 10;
            foreach ($params['video_ids'] as $videoId) {
                $model = new PapperVideo();
                $model->video_id = $videoId;
                $model->papper_id = $params['papper_id'];
                $model->sort = $sort;
                $model->save();
                $sort += 10;
            }
            return true;
        });
    }
    
    public function sortVideo(array $params) {
        if (!isset($params['papper_id']) || !$params['papper_id']){
            throw new \Exception('文案ID不能为空', Code::PARAMETER_ERROR);
        }
        if (!isset($params['pre_id']) || !$params['pre_id']){
            throw new \Exception('前ID不能为空', Code::PARAMETER_ERROR);
        }
        if (!isset($params['next_id']) || !$params['next_id']){
            throw new \Exception('后ID不能为空', Code::PARAMETER_ERROR);
        }
        return DB::transaction(function () use ($params) {
            if (!$preGoods = PapperVideo::where('video_id', $params['pre_id'])->where('papper_id', $params['papper_id'])->first()) {
                throw new \Exception('前ID不存在', Code::EMPTY_DATA);
            }
            if (!$nextGoods = PapperVideo::where('video_id', $params['next_id'])->where('papper_id', $params['papper_id'])->first()) {
                throw new \Exception('后ID不存在', Code::EMPTY_DATA);
            }
            $nextSort = $nextGoods->sort;
            $nextGoods->sort = $preGoods->sort;
            $nextGoods->save();
            $preGoods->sort = $nextSort;
            $preGoods->save();
            return true;
        });
    }
}
